package site.yunnong.atvris.portal.service.impl;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import site.yunnong.atvris.common.api.Page;
import site.yunnong.atvris.common.utils.DateUtils;
import site.yunnong.atvris.common.utils.RedisKeyUtils;
import site.yunnong.atvris.dao.domain.User;
import site.yunnong.atvris.service.InteractionService;
import site.yunnong.atvris.service.UserService;
import site.yunnong.atvris.common.dto.UserFansQueryParam;
import site.yunnong.atvris.common.dto.UserFollowQueryParam;
import site.yunnong.atvris.service.helper.OperatorHelper;
import site.yunnong.atvris.portal.service.FollowService;
import site.yunnong.atvris.service.vo.UserFansVO;
import site.yunnong.atvris.service.vo.UserFollowVO;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

/**
 * @author zjh
 * @date 2021/9/20 17:00
 */
@Slf4j
@Service
public class FollowServiceImpl implements FollowService {

    @Resource
    private InteractionService interactionService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private UserService userService;

    @Override
    public Page<UserFollowVO> queryFollowList(UserFollowQueryParam param) {
        long followCount = interactionService.findUserFollowCount(param.getUuid());
        List<UserFollowVO> followList = findFollowList(param.getUuid(), param.getPageNum(), param.getPageSize());
        return new Page<>(param.getPageNum(), param.getPageSize(), followCount, followList);   
    }

    @Override
    public Page<UserFansVO> queryFansList(UserFansQueryParam param) {
        long fansCount = interactionService.findUserFansCount(param.getUuid());
        List<UserFansVO> fansList = findFansList(param.getUuid(), param.getPageNum(), param.getPageSize());
        return new Page<>(param.getPageNum(), param.getPageSize(), fansCount, fansList);
    }

    private List<UserFansVO> findFansList(Long uuid, Integer pageNum, Integer pageSize) {
        String userFansKey = RedisKeyUtils.getUserFansKey(uuid);
        int offset = (pageNum - 1) * pageSize;
        Set<Long> targetIds = redisTemplate.opsForZSet().reverseRange(userFansKey, offset, offset + pageSize - 1);

        if (targetIds == null) {
            return Lists.newArrayList();
        }
        Long loginUuid = null;
        if(OperatorHelper.isLogin()) {
            loginUuid = OperatorHelper.getLoginUuid();
        }
        List<UserFansVO> result = Lists.newArrayList();
        for (Long targetId : targetIds) {
            UserFansVO vo = new UserFansVO();
            User user = userService.queryByUuid(targetId);
            BeanUtils.copyProperties(user, vo);
            // 判断当前登录的用户是否关注了该用户
            vo.setHasFollowed(interactionService.hasFollowed(loginUuid, targetId));
            result.add(vo);
        }
        return result;
    }

    private List<UserFollowVO> findFollowList(Long uuid, Integer pageNum, Integer pageSize) {
        Set<Long> targetIds = interactionService.findUserFollowList(uuid, pageNum, pageSize);
        String userFollowKey = RedisKeyUtils.getUserFollowKey(uuid);
        
        if (targetIds == null) {
            return Lists.newArrayList();
        }
        Long loginUuid = null;
        if(OperatorHelper.isLogin()) {
            loginUuid = OperatorHelper.getLoginUuid();
        }
        List<UserFollowVO> result = Lists.newArrayList();
        for (Long targetId : targetIds) {
            UserFollowVO vo = new UserFollowVO();
            User user = userService.queryByUuid(targetId);
            BeanUtils.copyProperties(user, vo);
            // set 关注时间
            Double score = redisTemplate.opsForZSet().score(userFollowKey, targetId);
            LocalDateTime createTime = DateUtils.getDateTimeOfTimeStamp(score.longValue());
            vo.setCreateTime(createTime);
            // 判断当前登录的用户是否关注了该用户
            vo.setHasFollowed(interactionService.hasFollowed(loginUuid, targetId));
            result.add(vo);
        }
        return result;
    }
}
